package main

import (
	"context"
	"errors"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/metadata"
	"google.golang.org/grpc/status"
	"grpc_starter/grpc_interceptor/pb/pb"
	"net"
)

type server struct {
}

func (s *server) Say(ctx context.Context, reqData *pb.ReqData) (*pb.ResData, error) {
	return &pb.ResData{Data: "hello " + reqData.Message}, nil
}

const (
	protocol = "tcp"
	address  = "127.0.0.1:5001"
)

// judgment the auth information submitted of client
func auth(ctx context.Context) error {
	md, ok := metadata.FromIncomingContext(ctx)
	if !ok {
		return errors.New("not auth info")
	}

	var (
		xToken string
		appId  string
	)

	if val, ok := md["x_token"]; ok {
		xToken = val[0]
	} else {
		return errors.New("not auth info of x_token")
	}

	if val, ok := md["app_id"]; ok {
		appId = val[0]
	} else {
		return errors.New("not auth info of app_id")
	}

	if xToken != "123" || appId != "456" {
		return status.Errorf(codes.PermissionDenied, "not auth info x_token=[%s],app_id=[%s]", xToken, appId)
	}

	return nil
}

func myServerInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
	if err = auth(ctx); err != nil {
		return nil, err
	}
	return handler(ctx, req)
}

func main() {
	// custom interceptor on the server
	ops := grpc.UnaryInterceptor(myServerInterceptor)

	listen, _ := net.Listen(protocol, address)

	s := grpc.NewServer(ops)

	pb.RegisterGreetServer(s, new(server))

	_ = s.Serve(listen)
}
